package ch.areion.areionapp.core;

import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import ch.areion.areionapp.Main;
import ch.areion.areionapp.R;
import ch.areion.areionapp.communication.Monitor;
import ch.areion.areionapp.engine.IEngine;
import ch.areion.areionapp.engine.MotorSide;
import ch.areion.areionapp.core.Controller;
import ch.areion.common.message.Module;
import ch.areion.common.message.Type;
import ch.areion.common.message.Version;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

/**
 * With this Class, the individual functions can be tested.
 * 
 * @author IljasaRedzepi
 * @version 0.1
 */

public class Testing extends IOIOActivity {
	private Button button_driveForward;
	private Button button_driveBoxCurve;
	private Button button_driveLeftCurve;
	private Button button_driveRightCurve;
	private Button button_driveParcour;
	private Button button_stopAreion;
	public TextView text_EngineResponse;

	private SeekBar pid_lp;
	private SeekBar pid_li;
	private SeekBar pid_ld;
	private SeekBar pid_rp;
	private SeekBar pid_ri;
	private SeekBar pid_rd;

	/**
	 * this method will called every time when the testing application is
	 * started.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.testing);
		//engine = Controller.getEngine();
		

		button_driveForward = (Button) findViewById(R.id.button_driveForward);
		button_driveBoxCurve = (Button) findViewById(R.id.button_driveBoxCurve);
		button_driveLeftCurve = (Button) findViewById(R.id.button_driveLeftCurve);
		button_driveRightCurve = (Button) findViewById(R.id.button_driveRightCurve);
		button_driveParcour = (Button) findViewById(R.id.button_driveParcour);
		button_stopAreion = (Button) findViewById(R.id.button_stopAreion);

		pid_lp = (SeekBar) findViewById(R.id.pid_lp);
		pid_li = (SeekBar) findViewById(R.id.pid_li);
		pid_ld = (SeekBar) findViewById(R.id.pid_ld);
		pid_rp = (SeekBar) findViewById(R.id.pid_rp);
		pid_ri = (SeekBar) findViewById(R.id.pid_ri);
		pid_rd = (SeekBar) findViewById(R.id.pid_rd);

		/**
		 * button listener to drive forward.
		 */
		button_driveForward.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Monitor.getInstance().add(Version.V01, Type.INFO,
							Module.CORE, "Test, driveForward");
					IEngine eng = Controller.getEngine();
					eng.driveStraight(500);
					
				} catch (ConnectionLostException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Connection lost to IOIO. " + e.getMessage());
					e.printStackTrace();
				} catch (InterruptedException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Testing interrupted. " + e.getMessage());
					e.printStackTrace();
				}

			}
		});

		/**
		 * button listener to drive box curve.
		 */
		button_driveBoxCurve.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Monitor.getInstance().add(Version.V01, Type.INFO,
							Module.CORE, "Test, driveBoxCurve");
					IEngine eng = Controller.getEngine();
					eng.driveAlongLine(300, 500);
				} catch (ConnectionLostException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Connection lost to IOIO. " + e.getMessage());
					e.printStackTrace();
				} catch (InterruptedException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Testing interrupted. " + e.getMessage());
					e.printStackTrace();
				}

			}
		});
		
		/**
		 * button listener to drive left curve.
		 */
		button_driveLeftCurve.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Monitor.getInstance().add(Version.V01, Type.INFO,
							Module.CORE, "Test, driveLeftCurve");
					IEngine eng = Controller.getEngine();
					eng.correctAngle(); // check orientation
				} catch (ConnectionLostException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Connection lost to IOIO. " + e.getMessage());
					e.printStackTrace();
				} catch (InterruptedException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Testing interrupted. " + e.getMessage());
					e.printStackTrace();
				}

			}
		});
		
		/**
		 * button listener to drive right curve
		 */
		button_driveRightCurve.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Monitor.getInstance().add(Version.V01, Type.INFO,
							Module.CORE, "Test, driveRightCurve");
					IEngine eng = Controller.getEngine();
					eng.correctAngle(); // check orientation
				} catch (ConnectionLostException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Connection lost to IOIO. " + e.getMessage());
					e.printStackTrace();
				} catch (InterruptedException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Testing interrupted. " + e.getMessage());
					e.printStackTrace();
				}

			}
		});
		
		/**
		 * button listener to drive parcour. 
		 */
		button_driveParcour.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Monitor.getInstance().add(Version.V01, Type.INFO,
							Module.CORE, "Test, driveParcour");
					Controller contr = Main.getControllerInstance();
					contr.start();
				} catch (ConnectionLostException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Connection lost to IOIO. " + e.getMessage());
					e.printStackTrace();
				} catch (InterruptedException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Testing interrupted. " + e.getMessage());
					e.printStackTrace();
				}
			}
		});
		
		/**
		 * button listener to stop areion.
		 */
		button_stopAreion.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					Monitor.getInstance().add(Version.V01, Type.INFO,
							Module.CORE, "Test, stopAreion");
					IEngine eng = Controller.getEngine();
					eng.stop();
				} catch (ConnectionLostException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Connection lost to IOIO. " + e.getMessage());
					e.printStackTrace();
				} catch (InterruptedException e) {
					Monitor.getInstance().add(Version.V01, Type.ERROR,
							Module.CORE,
							"Testing interrupted. " + e.getMessage());
					e.printStackTrace();
				}
			}
		});

		pid_lp.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				updateLPid();
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
			}
		});
		pid_li.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				updateLPid();
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
			}
		});
		pid_ld.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				updateLPid();
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
			}
		});

		pid_rp.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				updateRPid();
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
			}
		});
		pid_ri.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				updateRPid();
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
			}
		});
		pid_rd.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				updateRPid();
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
			}
		});
	}

	private void updateLPid() {
		byte p = (byte) pid_lp.getProgress();
		byte i = (byte) pid_li.getProgress();
		byte d = (byte) pid_ld.getProgress();

		try {
			IEngine eng = Controller.getEngine();
			//eng.setPID(MotorSide.LEFT, p, i, d);
			Monitor.getInstance().add(Version.V01, Type.INFO, Module.ENGINE,
					"PID-Left P", String.format("%d", p));
			Monitor.getInstance().add(Version.V01, Type.INFO, Module.ENGINE,
					"PID-Left I", String.format("%d", i));
			Monitor.getInstance().add(Version.V01, Type.INFO, Module.ENGINE,
					"PID-Left D", String.format("%d", d));
		} catch (Exception e) {
			Monitor.getInstance().add(Version.V01, Type.WARNING, Module.ENGINE,
					"Unable to set left pid value.");
		}
	}

	private void updateRPid() {
		byte p = (byte) pid_rp.getProgress();
		byte i = (byte) pid_ri.getProgress();
		byte d = (byte) pid_rd.getProgress();

		try {
			IEngine eng = Controller.getEngine();
			//eng.setPID(MotorSide.RIGHT, p, i, d);
			Monitor.getInstance().add(Version.V01, Type.INFO, Module.ENGINE,
					"PID-Right P", String.format("%d", p));
			Monitor.getInstance().add(Version.V01, Type.INFO, Module.ENGINE,
					"PID-Right I", String.format("%d", i));
			Monitor.getInstance().add(Version.V01, Type.INFO, Module.ENGINE,
					"PID-Right D", String.format("%d", d));
		} catch (Exception e) {
			Monitor.getInstance().add(Version.V01, Type.WARNING, Module.ENGINE,
					"Unable to set right pid value.");
		}
	}
	
	/**
	 * this method return the ioiolooper instance.
	 * @return ioiolooper instance
	 */
	@Override
	protected IOIOLooper createIOIOLooper() {
		return Main.getControllerInstance();
	}
	public void onBackPressed() {
		super.onBackPressed();
	}
}
